home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / graph / _planar_map.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  6.4 KB  |  335 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _planar_map.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/planar_map.h>
  16.  
  17. extern bool PLANAR(graph&, bool=false);
  18.  
  19. list<edge> planar_map::adj_edges(face f) const
  20. { list<edge> result(f->head);
  21.   edge e1 = succ_face_edge(f->head);
  22.   while (e1!=f->head)
  23.   { result.append(e1);
  24.     e1 = succ_face_edge(e1);
  25.    }
  26.   return result;
  27.  }
  28.  
  29. list<node> planar_map::adj_nodes(face f) const
  30. { list<node> result(source(f->head));
  31.   edge e1 = succ_face_edge(f->head);
  32.   while (e1!=f->head)
  33.   { result.append(source(e1));
  34.     e1 = succ_face_edge(e1);
  35.    }
  36.   return result;
  37.  }
  38.  
  39. list<face> planar_map::adj_faces(node v) const
  40. { list<face> result;
  41.   edge e;
  42.   forall_out_edges(e,v) result.append(adj_face(e));
  43.   return result;
  44.  }
  45.  
  46. face  planar_map::new_face(GenPtr i) 
  47.   face f=new i_face(i,this);
  48.   f->loc=F_list.append(f);
  49.   return f;
  50.  }
  51.  
  52.  
  53. edge planar_map::split_edge(edge e, GenPtr node_inf)
  54.   /* splits edge e and its reversal by inserting a new node u (node_inf) 
  55.  
  56.               e                          e           rr
  57.         ----------->                --------->   --------->
  58.      (v)            (w)   ====>  (v)          (u)          (w)
  59.         <-----------                <---------   <---------
  60.               r                          er          r
  61.  
  62.      returns edge rr
  63.   */
  64.  
  65.  
  66.   edge r = e->rev;
  67.  
  68.   node v = source(e);
  69.   node w = target(e);
  70.  
  71.   node u = graph::new_node();
  72.  
  73.   copy_node_entry(node_inf);
  74.  
  75.   u->data[0] = node_inf;
  76.  
  77.   e->t = u;
  78.   r->t = u;
  79.  
  80.   edge rr = graph::new_edge(u,w);
  81.   edge er = graph::new_edge(u,v);
  82.  
  83.   FACE(rr) = FACE(e);
  84.   FACE(er) = FACE(r);
  85.  
  86.   r->rev  = rr;
  87.   rr->rev = r;
  88.  
  89.   e->rev  = er;
  90.   er->rev = e;
  91.  
  92.   return rr;
  93.  
  94. }
  95.  
  96.  
  97. edge planar_map::new_edge(edge e1, edge e2, GenPtr face_i)
  98.  /* cout << "NEW_EDGE:\n";
  99.     print_edge(e1); cout << " F = " << int(adj_face(e1)) << "\n";
  100.     print_edge(e2); cout << " F = " << int(adj_face(e2)) << "\n";
  101.     newline;
  102.   */
  103.  
  104.   if (adj_face(e1) != adj_face(e2)) 
  105.     error_handler(1,"planar_map::new_edge: new edge must split a face."); 
  106.  
  107.   face F = adj_face(e1);
  108.   face f = new_face(face_i);
  109.  
  110.   edge y = graph::new_edge(e1,source(e2),before);
  111.   F->head = y;
  112.   FACE(y) = F;
  113.   
  114.   edge x = graph::new_edge(e2,source(e1),before);
  115.   f->head = x;
  116.   FACE(x) = f;
  117.  
  118.   x->rev = y;
  119.   y->rev = x;
  120.  
  121.   for (edge e = succ_face_edge(x); e != x; e = succ_face_edge(e)) 
  122.      FACE(e) = f;
  123.  
  124.   return y;
  125. }
  126.  
  127.  
  128. node planar_map::new_node(const list<edge>& el, GenPtr node_inf)
  129. {
  130.   if (el.length() < 2)
  131.       error_handler(1,"planar_map::new_node(el,i):  el.length() < 2."); 
  132.  
  133.   list_item it = el.first();
  134.  
  135.   edge e0 = el[it];
  136.  
  137.   it = el.succ(it);
  138.  
  139.   face f = adj_face(e0);
  140.  
  141.   edge e;
  142.   forall(e,el)
  143.   { if (adj_face(e) != f)
  144.       error_handler(1,"planar_map::new_node: edges bound different faces."); 
  145.    }
  146.  
  147.   e = el[it];
  148.  
  149.   it = el.succ(it);
  150.  
  151.   GenPtr face_inf = f->inf;
  152.  
  153.   copy_face_entry(face_inf);
  154.   copy_node_entry(node_inf);
  155.  
  156.   edge e1 = split_edge(new_edge(e0,e,face_inf),node_inf);
  157.  
  158.   node u = source(e1);
  159.  
  160.   while(it)
  161.   { copy_face_entry(face_inf);
  162.     e1 = new_edge(e1,el[it],face_inf);
  163.     it = el.succ(it);
  164.    }
  165.  
  166.   return u;
  167. }
  168.  
  169. node planar_map::new_node(face f, GenPtr node_inf)
  170. { return new_node(adj_edges(f),node_inf);
  171.  }
  172.  
  173.  
  174. void planar_map::del_edge(edge x, GenPtr face_i)
  175. {
  176.   edge y  = reverse(x);
  177.   face F1 = adj_face(x);
  178.   face F2 = adj_face(y);
  179.  
  180.   edge e = succ_face_edge(y);
  181.  
  182.   F1->inf = face_i;
  183.  
  184.   if (F1!=F2)
  185.   { edge e = succ_face_edge(y);
  186.     F1->head = e;
  187.     while (e!=y)
  188.     { FACE(e) = F1;
  189.       e = succ_face_edge(e);
  190.      }
  191.  
  192.     del_face(F2);
  193.    }
  194.   else
  195.   { e = succ_face_edge(e);
  196.  
  197.     if (e!=y) // no isolated edge
  198.       F1->head = e;   
  199.     else 
  200.       del_face(F1);
  201.  
  202.    }
  203.  
  204.   graph::del_edge(x);
  205.   graph::del_edge(y);
  206.  
  207. }
  208.  
  209.  
  210. void planar_map::clear() 
  211. { face f;
  212.   forall(f,F_list) 
  213.   { clear_face_entry(f->inf);
  214.     delete f;
  215.    }
  216.   F_list.clear();
  217.   graph::clear();
  218.  }
  219.  
  220. planar_map::planar_map(const graph& G) : graph(G)
  221.  
  222. // input: planar embedded graph represented by a bidirected directed graph G 
  223. // i.e., for each node v of G the adjacent edges are sorted counter-clockwise. 
  224. // computes planar map representation (faces!)
  225. // For each face F the information of one of its edges is copied into F
  226.  
  227.   edge e,e1;
  228.   edge_array<edge> Rev(*this);
  229.  
  230.   if (compute_correspondence(*this,Rev) == false)
  231.      error_handler(999,"planar_map: graph is not bidirected");
  232.  
  233.   if (!PLANAR(*this)) 
  234.      error_handler(1,"planar_map: Graph is not planar."); 
  235.  
  236.  
  237.   forall_edges(e,*this) e->rev = Rev[e];
  238.  
  239.  
  240.   Rev.clear();
  241.  
  242.   // compute faces
  243.  
  244.   edge_array<bool> F(*this,false);
  245.  
  246.   forall_edges(e,*this)
  247.    if (!F[e])
  248.     { F[e] = true;
  249.       face f = new_face(e->data[0]);  // copy entry of first edge into face
  250.       G.copy_edge_entry(f->inf);
  251.       e->data[0] =  f;
  252.       f->head = e;
  253.       e1 = succ_face_edge(e);
  254.       while (e1 != e)
  255.       { e1->data[0] = f;
  256.         F[e1] = true;
  257.         e1 = succ_face_edge(e1);
  258.        }
  259.      } 
  260.  
  261.  
  262.  
  263. list<edge> planar_map::triangulate()
  264. {
  265.   node v,w;
  266.   edge e,e1,e2,e3;
  267.  
  268.   list<edge> L;
  269.  
  270.   node_array<bool> marked(*this,false);
  271.  
  272.   forall_nodes(v,*this)
  273.   {
  274.     list<edge> El = adj_edges(v);
  275.  
  276.     forall(e,El) marked[target(e)] = true;
  277.  
  278.     forall(e,El)
  279.     { 
  280.       e1 = e;
  281.       e2 = succ_face_edge(e1);
  282.       e3 = succ_face_edge(e2);
  283.  
  284.       face F = FACE(e1);
  285.  
  286.       while (target(e3) != v)
  287.       { 
  288.  
  289.         // e1,e2 and e3 are the first three edges in a clockwise 
  290.         // traversal of a face incident to v and t(e3) is not equal
  291.         // to v.
  292.  
  293.         if ( !marked[target(e2)] )
  294.         { 
  295.           // we mark w and add the edge {v,w} inside F, i.e., after
  296.           // dart e1 at v and after dart e3 at w.
  297.  
  298.           marked[target(e2)] = true;
  299.   
  300.           e1 = new_edge(e1,e3,F->inf);
  301.           e2 = e3;
  302.           e3 = succ_face_edge(e2);
  303.  
  304.           L.append(e1);
  305.         }
  306.         else
  307.         { // we add the edge {source(e2),target(e3)} inside F, i.e.,
  308.           // after dart e2 at source(e2) and before dart 
  309.           // reversal_of[e3] at target(e3).
  310.  
  311.           e3 = succ_face_edge(e3); 
  312.  
  313.           e2 = new_edge(e2,e3,F->inf);
  314.  
  315.           L.append(e2);
  316.  
  317.         }
  318.       } //end of while
  319.  
  320.     } //end of stepping through incident faces
  321.  
  322.    forall_adj_nodes(w,v) marked[w] = false;
  323.  
  324.   } // end of stepping through nodes
  325.  
  326.  return L;
  327.  
  328. }
  329.